using Blog2025.Application.Common;
using Blog2025.Application.Dto;
using Blog2025.Application.Extensions;
using Blog2025.Domain.Entities.App;
using Blog2025.Domain.Filters;
using Blog2025.Domain.Repositories;
using MediatR;

namespace Blog2025.Application.Services;
public class UserAppServices : IUserAppServices
{
    private readonly IRepository<AppUser> _userRepo;
    private readonly IRepository<AppRole> _roleRepo;
    private readonly IFilter<AppUser> _filter;
    private readonly IMediator _mediator;

    public UserAppServices(IRepository<AppUser> userRepo, IRepository<AppRole> roleRepo,IFilter<AppUser> filter,IMediator mediator)
    {
        _userRepo = userRepo;
        _roleRepo = roleRepo;
        _filter=filter;
        _mediator = mediator;
    }

    public async Task<dynamic> GetAllAsync(PageRequestDto pageRequestDto)
    {
        var users = await _userRepo.GetPagedAsync(pageRequestDto.PageIndex,pageRequestDto.PageSize);
        int totalCount=users.Count();
        int totalPage=(int)Math.Ceiling((double)users.Count() / pageRequestDto.PageSize);
        int pageIndex=pageRequestDto.PageIndex;
        int pageSize=pageRequestDto.PageSize;
        var items=users.Select(u => new UserDto { Id = u.Id, Username = u.Username, Nickname = u.Nickname, AvatarUrl = u.AvatarUrl, IsEnabled = u.IsActived });
        return PageResult.Success(totalCount,totalPage,pageIndex,pageSize,items);
    }
    // 过滤器
    public async Task<dynamic> GetFilterAsync(Dictionary<string ,object> filters)
    {
        var users=await _userRepo.GetAllAsync();
        return _filter.Filter(users,filters);
    }

    public async Task<UserDto> GetByIdAsync(Guid id)
    {
        var u = await _userRepo.GetByIdAsync(id) ?? throw new Exception("用户不存在");
        return new UserDto { Id = u.Id, Username = u.Username, Nickname = u.Nickname, AvatarUrl = u.AvatarUrl, IsEnabled = u.IsActived };
    }

    public async Task CreateAsync(CreateUserDto dto)
    {
        var salt = Guid.NewGuid().ToString("N");
        var pwdHash = HashPassword(dto.Password, salt);
        // var user = new AppUser { Username = dto.Username, Password = pwdHash, Salt = salt };
        // 使用静态工厂方法创建用户（自动发布事件）
        var user=AppUser.Create(dto.Username,pwdHash,salt);
        await _userRepo.CreateAsync(user);
        // 发布领域事件
        await _mediator.PublishDomainEventsAsync(user);
    }

    public async Task UpdateAsync(Guid id, UpdateUserDto dto)
    {
        var user = await _userRepo.GetByIdAsync(id) ?? throw new Exception("用户不存在");
        if (!string.IsNullOrEmpty(dto.Nickname)) user.UpdateNickname(dto.Nickname);
        if (!string.IsNullOrEmpty(dto.AvatarUrl)) user.UpdateAvatar(dto.AvatarUrl);
        user.DepartmentId=dto.DepartmentId;
        await _userRepo.UpdateAsync(user);
    }

    public async Task DeleteAsync(Guid id)
    {
        var user = await _userRepo.GetByIdAsync(id) ?? throw new Exception("用户不存在");
        await _userRepo.DeleteAsync(user);
    }

    public async Task EnableAsync(Guid id)
    {
        var user = await _userRepo.GetByIdAsync(id) ?? throw new Exception("用户不存在");
        user.Enable();
        await _userRepo.UpdateAsync(user);
    }

    public async Task<ApiResult> DisableAsync(Guid id)
    {
        var user = await _userRepo.GetByIdAsync(id);
        if (user == null)
        {
            return ApiResult.Fail(ErrorCodes.NotFound, "用户不存在或已经删除");
        }

        user.Disable();
        await _userRepo.UpdateAsync(user);
        return ApiResult.Success(user);
    }

    public async Task AssignRoleAsync(Guid userId, Guid roleId)
    {
        var user = await _userRepo.GetByIdAsync(userId) ?? throw new Exception("用户不存在");
        var role = await _roleRepo.GetByIdAsync(roleId) ?? throw new Exception("角色不存在");
        user.AssignRole(role);
        await _userRepo.UpdateAsync(user);
    }

    public async Task RemoveRoleAsync(Guid userId, Guid roleId)
    {
        var user = await _userRepo.GetByIdAsync(userId) ?? throw new Exception("用户不存在");
        var role = await _roleRepo.GetByIdAsync(roleId) ?? throw new Exception("角色不存在");
        user.RemoveRole(role);
        await _userRepo.UpdateAsync(user);
    }

    public async Task UpdateAvatarAsync(Guid userId, string avatarUrl)
    {
        var user = await _userRepo.GetByIdAsync(userId) ?? throw new Exception("用户不存在");
        user.UpdateAvatar(avatarUrl);
        await _userRepo.UpdateAsync(user);
    }

    public async Task UpdateNicknameAsync(Guid userId, string nickname)
    {
        var user = await _userRepo.GetByIdAsync(userId) ?? throw new Exception("用户不存在");
        user.UpdateNickname(nickname);
        await _userRepo.UpdateAsync(user);
    }

    public async Task ChangePasswordAsync(Guid userId, string oldPwd, string newPwd)
    {
        var user = await _userRepo.GetByIdAsync(userId) ?? throw new Exception("用户不存在");
        var oldHash = HashPassword(oldPwd, user.Salt);
        var newHash = HashPassword(newPwd, user.Salt);
        user.ChangePassword(oldHash, newHash);
        await _userRepo.UpdateAsync(user);
    }

    private string HashPassword(string pwd, string salt)
    {
        using var sha256 = System.Security.Cryptography.SHA256.Create();
        var bytes = System.Text.Encoding.UTF8.GetBytes(pwd + salt);
        var hash = sha256.ComputeHash(bytes);
        return Convert.ToBase64String(hash);
    }
}